﻿using System;
using System.Collections.Generic;
using System.Text;
using MVCFoto.Model;
using System.Web.Caching;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;

namespace MVCFoto.BLL
{
    /// <summary>
    /// 系统设定辅助类
    /// </summary>
    public class MVCFotoSettings
    {
        public const string MVCFotoVersion = "MVCFoto 0.1alpha";
        /* 从数据库取得设置
        private static readonly MVCFoto.IDAL.ISystemSettings settings = MVCFoto.DALFactory.Factory.Create<MVCFoto.IDAL.ISystemSettings>("SystemSettings");

        private static object getAllSettingsLock = new object();
        private static object getKeyLock = new object();
        public static IList<SystemSettingInfo> GetAllSettings()
        {
            return CacheHelper.GetCacheItem<IList<SystemSettingInfo>>("MF_Cache_SystemSettings",
                getAllSettingsLock,            
                TimeSpan.FromMinutes(30),
                delegate {
                    return settings.GetAllSettings();
                }
                );
        }

        public string GetKey(string settingsKey)
        {
            return CacheHelper.GetCacheItem<string>(String.Format("MF_Cache_SystemSetting_{0}", settingsKey.ToLower()),
                getKeyLock,
                TimeSpan.FromMinutes(30),
                delegate
                {
                    IList<SystemSettingInfo> settings = GetAllSettings();
                    if (settings != null)
                    {
                        foreach (SystemSettingInfo ssi in settings)
                        {
                            if (ssi.Setting.ToLower() == settingsKey.ToLower())
                                return ssi.Value;
                        }
                    }
                 
                    throw new MVCFotoException("No such settings");
                });
        }
        */
        private const string CacheKeyPrefix = "MF_Cache_Settings_{0}";
        static XmlDocument _settingsDocument
        {
            get{return SettingsDocument();}
        }
        #region private
        private static string _path = AppRoot + Path.DirectorySeparatorChar + "config" +
                                      Path.DirectorySeparatorChar;
        private static string _filename = "MVCFotoSettings.config";
        private static XmlDocument SettingsDocument()
        {
            object settingsFile = HttpRuntime.Cache["MF_Cache_MVCFotoSettingsFile"];

            // Check for language file in cache
            if (settingsFile == null)
            {
                XmlDocument temp = new XmlDocument();
                XmlTextReader settingsReader = new XmlTextReader(_path + _filename);
                try
                {
                    temp.Load(settingsReader);
                    HttpRuntime.Cache.Insert("MF_Cache_MVCFotoSettingsFile", temp,
                                             new CacheDependency(_path + _filename));
                }
                catch (Exception e)
                {
                    throw new MVCFotoException(String.Format("Load \"~/config/{0}\" error:{1}", _filename, e.ToString()));
                    // Log.Add(LogTypes.Error, new User(0), -1, "Error reading umbracoSettings file: " + e.ToString());
                }
                finally
                {
                    settingsReader.Close();
                }
                return temp;
            }
            else
                return (XmlDocument)settingsFile;
        }
        
        private static T GetCachedItem<T>(string key, object syncLock, CacheHelper.GetCacheItemDelegate<T> getCacheItem)
        {
            return CacheHelper.GetCacheItem<T>(key, syncLock,_path + _filename, getCacheItem);
        }

        /// <summary>
        /// Get a settings value
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        private static string GetKey(string Key)
        {
            XmlNode node = _settingsDocument.DocumentElement.SelectSingleNode(Key);            
            return XmlHelper.GetNodeValue(node);
        }
        /// <summary>
        /// Get a settings node
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        private static XmlNode GetKeyAsNode(string Key)
        {
            if (Key == null)
                throw new ArgumentException("Key cannot be null");

            if (_settingsDocument == null || _settingsDocument.DocumentElement == null)
                return null;
            return _settingsDocument.DocumentElement.SelectSingleNode(Key);
        }
        #endregion

        #region public
        private static object siteNameLock = new object();
        /// <summary>
        /// 站点名称
        /// </summary>
        public static string SiteName
        {
            get
            {
                return GetCachedItem<string>(string.Format(CacheKeyPrefix, "SiteName"), siteNameLock,
                    delegate
                    {
                        return GetKey("/settings/content/site/SiteName");
                    });
            }
                
                
        }
       
        /// <summary>
        /// 新上传照片的存储目录,不存在则自动创建
        /// </summary>        
        public static string NewPhotoDirectory
        {

            get
            {
                string dir = System.Web.HttpContext.Current.Server.MapPath(PhotoDirectoyRoot);
                dir = Path.Combine(dir, String.Format(DateTime.Now.ToString("yyyyMM{0}dd{0}H{0}"), Path.DirectorySeparatorChar));
                if (!Directory.Exists(dir))
                    Directory.CreateDirectory(dir);
                return dir;

            }
        }
        
        /// <summary>
        /// 新上传照片的Url路径
        /// </summary>
        public static string NewPhotoUrl
        {
            get
            {
                string url = PhotoDirectoyRoot;
                if (!url.EndsWith("/"))
                    url += "/";
                return url + DateTime.Now.ToString("yyyyMM/dd/H/",System.Globalization.DateTimeFormatInfo.InvariantInfo);
                
            }
        }
        /// <summary>
        /// 用户头像目录,不存在则自动创建
        /// </summary>
        public static string UserAvatarDirectoy
        {
            get {
                string dir = HttpContext.Current.Server.MapPath(AvatarDirectoyRoot);
                int userId = User.MyID;
                if (userId > 0)
                {
                    //用户头像目录 0/1/1.jpg
                    dir = Path.Combine(dir, String.Format("{0}{2}{1}{2}", userId / 100, userId, Path.DirectorySeparatorChar));
                    if (!Directory.Exists(dir))
                        Directory.CreateDirectory(dir);
                    return dir;
                }
                else
                    return String.Empty;
            }
        }
        /// <summary>
        /// 用户头像Url路径
        /// </summary>
        public static string UserAvatarUrl
        {
            get
            {
                string url = AvatarDirectoyRoot;
                int userId = User.MyID;
                if (userId > 0)
                {
                    if (!url.EndsWith("/"))
                        url += "/";
                    //用户头像目录 0/1/1.jpg
                    return url + String.Format("{0}/{1}/", userId / 100, userId);

                }
                else
                    return String.Empty;
            }
        }

        private static object lockAvatarDirectoyRoot = new object();
        /// <summary>
        /// 头像存储根目录
        /// </summary>
        public static string AvatarDirectoyRoot
        {
            get {
                return GetCachedItem<string>(string.Format(CacheKeyPrefix, "AvatarDirectoyRoot"), lockAvatarDirectoyRoot,
                    delegate
                    {
                        string root = GetKey("/settings/content/user/AvatarDirectoryRoot");
                        if (String.IsNullOrEmpty(root))
                            throw new MVCFotoException("请设置用户头像目录.(/settings/content/user/AvatarDirectoryRoot)");
                        return root;
                    });
            }
        }

        private static object lockRequiresUniqueEmail = new object();
        /// <summary>
        /// 不允许相同Email重复注册
        /// </summary>
        public static bool RequiresUniqueEmail
        {
            get {
                return GetCachedItem<bool>(string.Format(CacheKeyPrefix, "RequiresUniqueEmail"), lockRequiresUniqueEmail,
                   delegate
                   {
                       try
                       {
                           return Boolean.Parse(GetKey("/settings/content/user/RequiresUniqueEmail"));
                       }
                       catch
                       {
                           AppLog.Add(AppLog.Nodes.Config, AppLog.LogTypes.Error, "配置文件节点/settings/content/user/RequiresUniqueEmail值不是正确的bool类型.");
                           return true;
                       }
                   });
            }
        }

        private static object lockMinUserNameLength = new object();
        /// <summary>
        /// <summary>
        /// 用户名最小长度
        /// </summary>
        public static int MinUserNameLength
        {
            get
            {
                return GetCachedItem<int>(string.Format(CacheKeyPrefix, "MinUserNameLength"), lockMinUserNameLength,
                 delegate
                 { 
                     return Int32.Parse(GetKey("/settings/content/user/MinUserNameLength")); 
                 });
            }
        }
        private static object photoDirectoryRootLock = new object();
        /// <summary>
        /// 相片存储根目录
        /// </summary>        
        public static string PhotoDirectoyRoot
        {
            get
            {
                return GetCachedItem<string>(string.Format(CacheKeyPrefix, "PhotoDirectoyRoot"), photoDirectoryRootLock,
                    delegate { return GetKey("/settings/content/image/Directory"); }
                    );
            }
        }

        private static object lockSingleSize = new object();
        /// <summary>
        /// 允许上传的单个文件大小
        /// </summary>
        public static long SingleSize
        {
            get {
                return GetCachedItem<long>(string.Format(CacheKeyPrefix, "SingleSize"), lockSingleSize,
                   delegate
                   {
                       string size = GetKey("/settings/content/image/SingleSize");
                       if (String.IsNullOrEmpty(size))
                           return 0;
                       return Utility.FileSizeHelper.ByteSize(size);
                   });
            }
        }

        private static object lockAllowedTypes = new object();
        /// <summary>
        /// 允许上传的文件类型
        /// </summary>
        public static string AllowedTypes
        {
            get
            {
                return GetCachedItem<string>(string.Format(CacheKeyPrefix, "AllowedTypes"), lockAllowedTypes,
                    delegate { return GetKey("/settings/content/image/AllowedTypes"); });
            }
        }

        private static object thumbnailSettingsLock = new object();
        /// <summary>
        /// 缩略图设置
        /// </summary>
        public static IList<ThumbnailSetting> ThumbnailSettings
        {
            get
            {
                return GetCachedItem<IList<ThumbnailSetting>>(string.Format(CacheKeyPrefix, "ThumbnailSettings"),
                    thumbnailSettingsLock,
                    delegate
                    {
                        XmlNode node = GetKeyAsNode("/settings/content/image/thumbnails");

                        if (node != null)
                        {
                            XmlNodeList thumbs = node.SelectNodes("./thumbnail");
                            if (thumbs != null)
                            {
                                IList<ThumbnailSetting> thumbnailSettings = new List<ThumbnailSetting>();
                                foreach (XmlNode xn in thumbs)
                                {

                                    ThumbnailSetting thumbnail = new ThumbnailSetting();
                                    string size = XmlHelper.GetNodeValue(xn);

                                    if (String.IsNullOrEmpty(size))
                                        //empty size definition
                                        continue;
                                    else
                                        thumbnail.Size = Int32.Parse(size);
                                    string corp = XmlHelper.GetNodeAttributeValue(xn, "crop");
                                    if (String.IsNullOrEmpty(corp))
                                        thumbnail.Crop = false;
                                    else
                                        thumbnail.Crop = Boolean.Parse(corp);

                                    thumbnailSettings.Add(thumbnail);
                                }
                                return thumbnailSettings;
                            }
                        }
                        return null;
                    });
            }
        }

        private static object lockCoverSize = new object();
        /// <summary>
        /// 取得相册封面大小
        /// </summary>       
        public static IList<ThumbnailSetting> ConverSize
        {           
            get
            {
                return GetCachedItem<IList<ThumbnailSetting>>(string.Format(CacheKeyPrefix, "ConverSize"), lockCoverSize,
                    delegate
                    {
                        XmlNode node = GetKeyAsNode("/settings/content/image/Covers");

                        if (node != null)
                        {
                            XmlNodeList thumbs = node.SelectNodes("./Cover");
                            if (thumbs != null)
                            {
                                IList<ThumbnailSetting> thumbnailSettings = new List<ThumbnailSetting>();
                                foreach (XmlNode xn in thumbs)
                                {

                                    ThumbnailSetting thumbnail = new ThumbnailSetting();
                                    string size = XmlHelper.GetNodeValue(xn);

                                    if (String.IsNullOrEmpty(size))
                                        //empty size definition
                                        continue;
                                    else
                                        thumbnail.Size = Int32.Parse(size);
                                    //是否覆盖原文件
                                    string overwrite = XmlHelper.GetNodeAttributeValue(xn, "default");
                                    if (String.IsNullOrEmpty(overwrite))
                                        thumbnail.OverWrite = false;
                                    else
                                        thumbnail.OverWrite = Boolean.Parse(overwrite);
                                    thumbnailSettings.Add(thumbnail);
                                }
                                return thumbnailSettings;
                            }
                        }
                        return null;
                    });
            }
        }
        
        /// <summary>
        /// 取得应用程序物理路径
        /// </summary>
        public static string AppRoot
        {
            get { return HttpRuntime.AppDomainAppPath; }
        }
        #endregion
    }



    //缩略图格式设定
    public class ThumbnailSetting 
    {
        /// <summary>
        /// 是否裁剪
        /// </summary>
        public bool Crop { get; set; }
        /// <summary>
        /// 大小
        /// </summary>
        public int Size { get; set; }    
        /// <summary>
        /// 是否覆盖原文件
        /// </summary>
        public bool OverWrite{get; set;}
    }
}
